/**************************************************************************************************
  Filename:       epl_rtc_m41t62.c
  Revised:        $Date: 2012-12-16$
  Revision:       $ TONG KUN LAI$

  Description:    Control of the RTC on the EcoBT board.

  Copyright 2012 EPL NTHU. All rights reserved.

**************************************************************************************************/

#include <ioCC2540.h>
#include "hal_types.h"
#include "epl_rtc_m41t62.h"





/*****local variable*****/
#define HAL_RTC_ALARM_BIT    BV(0)
uint8 slaveAddress = 0xd0; // 1101000 0
/************************/

/************************/
/** \brief  This is will initialize I2C interface and M41T62 RTC
* \param[in]       void
*/
void rtcInit(void)
{

  I2CInit();
  
  /*****Alarm interrupt setting*****/
//  PICTL |= 0x01;    // port interrupt control, 0 rising edge, 1 falling edge
//  P0IEN |= 0x01;    // IOC module, prot 0 interrupt mask, 0 interrupts are disabled, 1 interrupt s are enabled.
//  P0IE   = 1;       // CPU module, prot 0 interrupt mask, 0 interrupts are disabled, 1 interrupt s are enabled.
//  P0IFG  = 0x00;    // P0 interrupt Flag Status
//  P0IF   = 0;       // port 0 interrupt status flag
//  EA     = 1;       // enable interrupt
//  
  /*****RTC setting  *****/
  /*****Start RTC*****/
  I2CStart();
  while( I2CSentByte( slaveAddress ) != 0 );      // slave address 1101000 0 for write   
  while( I2CSentByte( RTC_M41T62_FLAGS ) != 0 );  // pointer to OF( oscillator fail bit) register
  while( I2CSentByte( 0x00 ) != 0 );              // set OF to 0
  I2CStop();	

} //  rtcInit function end

/** \brief	Write the Time data to M41T62 RTC
*
* Write the Time data to M41T62 RTC
*
* \param[in]       hour
*     hour data to write
* \param[in]       minute
*     minute data to write
* \param[in]       second
*     second data to write
*/
void rtcSetTime(uint8 hour, uint8 minute, uint8 second )
{
  I2CStart();
  while( I2CSentByte( slaveAddress ) != 0 );	// slave address 1101000 0
  while( I2CSentByte( RTC_M41T62_SECONDS ) != 0 );// seconds register
  while( I2CSentByte( second ) != 0 );            // write second
  while( I2CSentByte( minute ) != 0 );            // write minute
  while( I2CSentByte( hour ) != 0 );		// write hour
  I2CStop();
} // end function rtcSetTime

/** \brief	Read Time data to M41T62 RTC
*
* Read the Time data to M41T62 RTC
*
* \param[in]       hour
*     parameter for read  hour data of rtc
* \param[in]       minute
*     parameter for read  minute data of rtc 
* \param[in]       second
*     parameter for read  second data of rtc 
*/
void rtcGetTime( uint8* hour, uint8* minute, uint8* second )
{
  //uint8 slaveAddress = 0xd0; // 1101000 0
  // read sequence data 
  I2CStart();
  while( I2CSentByte( 0xd0 ) != 0 );		// slave address 1101000 0 for write
  while( I2CSentByte(RTC_M41T62_SECONDS ) != 0 );		// second register
  I2CStart();                                     // force re-start
  while( I2CSentByte( 0xd1 ) != 0 ); 		// slave address 1101000 1 for read
  *second = (I2CReceiveByte(LOW)& 0x7F);
  *minute = (I2CReceiveByte(LOW) & 0x7F);
  *hour   =  I2CReceiveByte(HIGH);
  I2CStop();

} // end function rtcGetTime


/** \brief	Write Date data to M41T62 RTC
*
* Write the Date data to M41T62 RTC
*
* \param[in]              day
*     dat data to write
* \param[in]              date
*     date data to write
* \param[in]              month
*     month data to write
* \param[in]              year
*     year data to write
* \param[in]              century
*     century data to write
*/
void rtcSetDate(uint8 day, uint8 date, uint8 month, uint8 year, uint8 century )
{
  I2CStart();
  while( I2CSentByte( slaveAddress ) != 0 );	          // slave address 1101000 0
  while( I2CSentByte( RTC_M41T62_DAY ) != 0 );            // pointer to day of week register
  while( I2CSentByte( BUILD_UINT8( 0x00, day) ) != 0 );   // write day,  BUILD_UINT8( RS(square wave output)register, day)
  while( I2CSentByte( ( date & 0x3F ) ) != 0 );           // write day of month
  while( I2CSentByte( ( (century << 6) | month ) ) != 0 );// write month cb1 cb0 0 10M month
                                                          //              0   0  0  0 0000
  while( I2CSentByte(  year ) != 0 );		          // write year
  I2CStop();
} // end function rtcSetDate


/** \brief	Read da data to M41T62 RTC
*
* Read the Time data to M41T62 RTC
*
* \param[in]       day
*     parameter for read  day data of rtc
* \param[in]       date
*     parameter for read  date data of rtc
* \param[in]       month
*     parameter for read  month data of rtc
* \param[in]       year
*     parameter for read  year data of rtc
* \param[in]       century
*     parameter for read  century data of rtc
*/
void rtcGetDate(uint8* day, uint8* date, uint8* month, uint8* year )
{
  I2CStart();
  while( I2CSentByte( 0xd0 ) != 0 );		// slave address 1101000 0 for write
  while( I2CSentByte(RTC_M41T62_DAY ) != 0 );	// days register
  I2CStart();                                   // force re-start
  while( I2CSentByte( 0xd1 ) != 0 ); 		// slave address 1101000 1 for read
  *day   = (I2CReceiveByte(LOW ));
  *date  =  I2CReceiveByte(LOW);
  *month = (I2CReceiveByte(LOW) & 0x1F);
  *year  = I2CReceiveByte(HIGH);
  I2CStop();
} // end function rtcGetDate


/** \brief	Read Time and Date data to M41T62 RTC
*
* Read the Time and Date data to M41T62 RTC
*
* \param[in]       hour
*     parameter for read  hour data of rtc
* \param[in]       minute
*     parameter for read  minute data of rtc 
* \param[in]       second
*     parameter for read  second data of rtc 
* \param[in]       day
*     parameter for read  day data of rtc
* \param[in]       date
*     parameter for read  date data of rtc
* \param[in]       month
*     parameter for read  month data of rtc
* \param[in]       year
*     parameter for read  year data of rtc
* \param[in]       century
*     parameter for read  century data of rtc
*/
void rtcReadDateAndTime(uint8* hour, uint8* minute, uint8* second, uint8* day
                        , uint8* date, uint8* month, uint8* year)
{
  /*****read sequence rtc data*****/
  I2CStart();
  while( I2CSentByte( slaveAddress ) != 0 );	// slave address 1101000 0 for write
  while( I2CSentByte( 0x01 ) != 0 );		// second register
  I2CStart();
  while( I2CSentByte( 0xd1 ) != 0 ); 		// slave address 1101000 1 for read
  *second = I2CReceiveByte(LOW) & 0x7F;
  *minute = I2CReceiveByte(LOW) & 0x7F; 
  *hour   = I2CReceiveByte(LOW);
  *day    = I2CReceiveByte(LOW);                // day of week
  *date   = I2CReceiveByte(LOW);                // day of month
  *month  = I2CReceiveByte(LOW) & 0x1F;
  *year   = I2CReceiveByte(LOW);
  I2CStop();
  
} // end rtcReadDateAndTime function

void halProcessAlarmInterrupt( uint8 alarmEvent )
{
 // HAL
}
 

/***************************************************************************************************
 *                                    INTERRUPT SERVICE ROUTINE
 ***************************************************************************************************/

/**************************************************************************************************
 * @fn      halKeyPort0Isr
 *
 * @brief   Port0 ISR
 *
 * @param
 *
 * @return
 **************************************************************************************************/
HAL_ISR_FUNCTION( halAlarmPort0Isr, P0INT_VECTOR )
{

  if ( P1IFG & HAL_RTC_ALARM_BIT )
  {
    halProcessAlarmInterrupt(1);
  }

  /*
    Clear the CPU interrupt flag for Port_0
    PxIFG has to be cleared before PxIF
  */
  P0IFG = 0;
  P0IF = 0;
}

